package cn.mrcode.wxsdk.web.common.ticket.lifeCycle.single;


import cn.mrcode.wxsdk.core.dialogue.common.exception.ReqException;
import cn.mrcode.wxsdk.core.dialogue.common.exception.WxException;
import cn.mrcode.wxsdk.web.common.ticket.TicketApi;
import cn.mrcode.wxsdk.web.common.ticket.lifeCycle.ITicketService;
import cn.mrcode.wxsdk.web.protocol.base.JsApiTicketInfo;

import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zhuqiang
 * @version V1.0
 * @Description: 单机版 ticket 生命周期维护
 * @date 2015/9/28 11:24
 */
public class TicketSingleService implements ITicketService {
    // 存放 JsApiTicketInfo 信息的map列表
    private static final ConcurrentHashMap<String, JsApiTicketInfo> ticketMap = new ConcurrentHashMap<String, JsApiTicketInfo>();
    private static ScheduledThreadPoolExecutor pool = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);
    static {
        TicketTask task = new TicketTask(ticketMap);
//        att.openTimeOutDestroy(true, Configure.accesstokenTimeOut * 2);  //2次超时还未被使用，则清除该token
        pool.scheduleAtFixedRate(task, 0, 10, TimeUnit.MINUTES);  // 10分钟执行一次 检测
    }
    private static Lock lock = new ReentrantLock();

    /**
     * 获取 jsApiTicke
     * @param appid
     * @param secret
     * @return
     */
    @Override
    public String getJsApiTicke(String appid, String secret) throws ReqException, WxException {
        lock.lock();
        try {
            boolean flag = ticketMap.containsKey(appid);
            if (flag) {
                JsApiTicketInfo jti = ticketMap.get(appid);
                jti.setLastUseTime(new Date());
                return jti.getJsapi_ticket();
            } else {
                JsApiTicketInfo jti = TicketApi.getJsApiTicketInfo(appid, secret);
                ticketMap.put(appid, jti);
                jti.setLastUseTime(new Date());
                return jti.getJsapi_ticket();
            }
        } finally {
            lock.unlock();
        }
    }

    private TicketSingleService(){};
    private static TicketSingleService instance = new TicketSingleService();
    public static TicketSingleService getInstance(){
        return instance;
    }
}
